<template>
  <el-container class="flow-panel-layout h_100vh">
    <el-header class="flow-panel-header p_0">
      <div class="header-content h_100 flex justify_between align_center">
        <div class="header-left overflow_hidden text_center font_bold">
          <img src="https://fengnull.gitee.io/picture_house/etl/ETL_logo.png" alt="" class="etl_logo">
        </div>
        <div class="font_bold">{{ data_etl.name }}设计</div>
        <div class="header-right pr_20">
          <el-tooltip class="box-item" effect="dark" v-if="data_etl.status === 0" content="保存草稿" placement="bottom">
            <img src="https://fengnull.gitee.io/picture_house/svg/save.svg" class="header-right-img" v-if="data_etl.status === 0" @click="handleSaveDraft" />
          </el-tooltip>
          <el-tooltip class="box-item" effect="dark" content="保存并运行" placement="bottom">
            <img src="https://fengnull.gitee.io/picture_house/svg/run.svg" class="header-right-img" @click="handleSaveAndRun" />
          </el-tooltip>
        </div>
      </div>
    </el-header>
    <el-container class="flow-panel-content">
      <flow-panel-libs @dragNodeStart="dragNodeStart"></flow-panel-libs>
      <el-container height="100%" class="flow-panel-content-wrap">
        <flow-panel-content></flow-panel-content>
        <el-footer height="400px" v-if="node_data_show" class="node-footer p_0">
          <div class="node-footer-title flex justify_between align_center fontsize_18 font_bolder pt_8 px_10 pb_12">
            <span>{{ nodeInfo.nodeName }}-结果集</span>
            <el-icon class="node-footer-close cursor_point" @click="node_data_show = false">
              <circle-close />
            </el-icon>
          </div>
          <node-data :requestFlag="requestFlag" :data_etl_id="data_etl_id" :node="nodeInfo"></node-data>
        </el-footer>
      </el-container>
    </el-container>
    <el-dialog v-model="etlDataModal" title="ETL数据" width="70%">
      <vxe-table v-loading="tableDataLoading" :tooltip-config="tableTooltipConfig" :element-loading-spinner="loadingSvg"
        element-loading-text="加载中..." element-loading-background="rgba(0, 0, 0, 0.8)"
        element-loading-svg-view-box="0, 0, 50, 50" border="full" height="500px" show-header-overflow
        :column-config="{resizable: true}" show-overflow :row-config="{isHover: true}" :data="showData">
        <vxe-column align="center" type="seq" width="60" field="序号" fixed></vxe-column>
        <vxe-column align="center" v-for="column in requestColumns" :key="column" :title="column" :field="column"
          sortable min-width="150" :filters="[{ data: '' }]" :filter-method="filterMethod">
          <template #filter="{ $panel, column }">
            <input type="type" v-for="(option, index) in column.filters" :key="index" v-model="option.data"
              @input="$panel.changeOption($event, !!option.data, option)" @keyup.enter="$panel.confirmFilter()"
              placeholder="按回车确认筛选">
          </template>
        </vxe-column>
      </vxe-table>
      <template #footer>
        <div class="footer-modal">
          <el-button @click="etlDataModal = false" size="small" class="footer-modal--btn">关闭
          </el-button>
        </div>
      </template>
    </el-dialog>
  </el-container>
</template>

<script>
import {
  computed,
  defineAsyncComponent,
  defineComponent,
  nextTick,
  onMounted,
  provide,
  reactive,
  ref,
} from "vue";
import { saveAndRunETL, saveDataETLDraft } from "../../../../service/data_etl";
import { CircleClose } from "@element-plus/icons-vue";
import { useEtlStore } from "../../../../store/flowEtl";
import { cloneDeep } from "lodash-es";
import { loadingSvg } from "../../../../utils/constant";
import { arrayToTreeById, findChildNode } from "../../../../utils/tree";

const NodeData = defineAsyncComponent(() => import("./node-data.vue"));
const FlowPanelLibs = defineAsyncComponent(() =>
  import("./flow-panel-libs.vue")
);
const FlowPanelContent = defineAsyncComponent(() =>
  import("./flow-panel-content.vue")
);

export default defineComponent({
  name: "MyFlowPanel",
  props: {},
  components: {
    FlowPanelLibs,
    FlowPanelContent,
    NodeData,
    CircleClose,
  },
  setup(props, ctx) {
    const etlStore = useEtlStore();
    const nodeInfo = ref({});
    const node_data_show = ref(false);
    const data_etl_id = computed(() => etlStore.data_etl_id);
    const data_etl = computed(() => etlStore.data_etl);
    const flowData = computed(() => etlStore.flowData);
    const nodeList = computed(() => etlStore.nodeList);
    const requestFlag = ref(false);
    const tableDataLoading = ref(false);
    const etlDataModal = ref(false);
    const showData = ref([]);
    const requestColumns = ref([]);
    const tableTooltipConfig = reactive({
      showAll: true,
      enterable: true,
      contentMethod: ({ type, column, row, items, _columnIndex }) => {
        const { property } = column;
        // 重写默认的提示内容
        if (property === "role" || property === "date") {
          if (type === "header") {
            return column.title ? column.title : "";
          }
          return row[property] ? row[property] : "";
        }
        // 其余的单元格使用默认行为
        return null;
      },
    });
    const dragNodeStart = (item) => {
      etlStore.setDragItem(item);
    };
    const handleSaveDraft = () => {
      saveDataETLDraft({
        content: JSON.stringify(flowData.value),
        data_etl_id: data_etl_id.value,
      }).then((res) => {
        ElMessage.success("草稿保存成功！");
      });
    };
    const handleSaveAndRun = () => {
      const statusLen = nodeList.value.filter((item) => !item.status);
      if (statusLen.length) {
        ElMessage.warning("存在未完成节点,请配置完成后保存！");
        return;
      }
      const output = nodeList.value.filter((item) => item.type === "output");
      if (!output.length || !output[0].status) {
        ElMessage.warning("ETL构建尚未完成！");
        return;
      } else if (output.length > 1) {
        ElMessage.warning("输出节点只能存在一个！");
        return;
      }
      let nodeTree = arrayToTreeById(
        flowData.value.lineList,
        "to",
        "from",
        output[0].id
      );
      let lineNodeList = findChildNode([nodeTree], output[0].id, "from");
      let allNodeList = nodeList.value.map((item) => item.id);
      if (new Set(lineNodeList).size !== new Set(allNodeList).size) {
        ElMessage.warning("存在不符合规则连线,请检查ETL配置！");
        return;
      }
      etlDataModal.value = true;
      tableDataLoading.value = true;
      node_data_show.value = false;
      saveAndRunETL({
        content: JSON.stringify(flowData.value),
        data_etl_id: data_etl_id.value,
      })
        .then((res) => {
          ElMessage.success(res.message);
          tableDataLoading.value = false;
          requestColumns.value = res.data.columns;
          if (res.data && res.data.rows.length) {
            showData.value = res.data.rows;
          }
        })
        .catch((err) => {
          ElMessage.success(err.message);
          tableDataLoading.value = false;
        });
    };
    const filterMethod = ({ option, row, column }) => {
      if (row[column.field]) {
        switch (typeof row[column.field]) {
          case "number":
          case "bigint":
            return row[column.field] === Number(option.data);
            break;
          case "string":
            return row[column.field].includes(option.data);
            break;
          default:
            return false;
            break;
        }
      } else {
        return false;
      }
    };
    const showNodeData = (node) => {
      nodeInfo.value = {};
      requestFlag.value = true;
      nodeInfo.value = cloneDeep(node);
      node_data_show.value = true;
      nextTick(() => {
        requestFlag.value = false;
      });
    };
    provide("showNodeData", showNodeData);
    onMounted(() => {});
    window.stores = { etlStore };
    return {
      nodeInfo,
      node_data_show,
      etlStore,
      data_etl_id,
      flowData,
      requestFlag,
      nodeList,
      data_etl,
      tableDataLoading,
      tableTooltipConfig,
      showData,
      requestColumns,
      loadingSvg,
      etlDataModal,
      filterMethod,
      showNodeData,
      dragNodeStart,
      handleSaveDraft,
      handleSaveAndRun,
    };
  },
});
</script>
<style lang="less">
@import "flowPanel.less";
</style>
